---
title: 'Prisma ORM MongoDB database connector'
sidebar_label: 'MongoDB'
metaTitle: 'MongoDB database connector'
metaDescription: 'How Prisma can connect to a MongoDB database using the MongoDB database connector.'
hidePage: false
tocDepth: 3
codeStyle: false
---

<TopBlock>

This guide discusses the concepts behind using Prisma ORM and MongoDB, explains the commonalities and differences between MongoDB and other database providers, and leads you through the process for configuring your application to integrate with MongoDB using Prisma ORM.

:::warning[MongoDB support for Prisma ORM v7]

**MongoDB support for Prisma ORM v7 is coming in the near future.** In the meantime, please use **Prisma ORM v6.19** (the latest v6 release) when working with MongoDB.

For getting started guides using Prisma ORM v6.19 with MongoDB, see:
- [Quickstart with MongoDB](/getting-started/prisma-orm/quickstart/mongodb)
- [Add to existing MongoDB project](/getting-started/prisma-orm/add-to-existing-project/mongodb)

:::

</TopBlock>

## What is MongoDB?

[MongoDB](https://www.mongodb.com/) is a NoSQL database that stores data in [BSON](https://bsonspec.org/) format, a JSON-like document format designed for storing data in key-value pairs. It is commonly used in JavaScript application development because the document model maps easily to objects in application code, and there is built in support for high availability and horizontal scaling.

MongoDB stores data in collections that do not need a schema to be defined in advance, as you would need to do with tables in a relational database. The structure of each collection can also be changed over time. This flexibility can allow rapid iteration of your data model, but it does mean that there are a number of differences when using Prisma ORM to work with your MongoDB database.

## Commonalities with other database providers

Some aspects of using Prisma ORM with MongoDB are the same as when using Prisma ORM with a relational database. You can still:

- model your database with the [Prisma Schema Language](/orm/prisma-schema)
- connect to your database, using the [`mongodb` database connector](/orm/overview/databases)
- use [Introspection](/orm/prisma-schema/introspection) for existing projects if you already have a MongoDB database
- use [`db push`](/orm/prisma-migrate/workflows/prototyping-your-schema) to push changes in your schema to the database
- use [Prisma Client](/orm/prisma-client) in your application to query your database in a type safe way based on your Prisma Schema

## Differences to consider

MongoDB's document-based structure and flexible schema means that using Prisma ORM with MongoDB differs from using it with a relational database in a number of ways. These are some areas where there are differences that you need to be aware of:

- **Defining IDs**: MongoDB documents have an `_id` field (that often contains an [ObjectID](https://www.mongodb.com/docs/manual/reference/bson-types/#std-label-objectid)). Prisma ORM does not support fields starting with `_`, so this needs to be mapped to a Prisma ORM field using the `@map` attribute. For more information, see [Defining IDs in MongoDB](/orm/prisma-schema/data-model/models#defining-ids-in-mongodb).

- **Migrating existing data to match your Prisma schema**: In relational databases, all your data must match your schema. If you change the type of a particular field in your schema when you migrate, all the data must also be updated to match. In contrast, MongoDB does not enforce any particular schema, so you need to take care when migrating. For more information, see [How to migrate old data to new schemas](#how-to-migrate-existing-data-to-match-your-prisma-schema).

- **Introspection and Prisma ORM relations**: When you introspect an existing MongoDB database, you will get a schema with no relations and will need to add the missing relations in manually. For more information, see [How to add in missing relations after Introspection](#how-to-add-in-missing-relations-after-introspection).

- **Filtering for `null` and missing fields**: MongoDB makes a distinction between setting a field to `null` and not setting it at all, which is not present in relational databases. Prisma ORM currently does not express this distinction, which means that you need to be careful when filtering for `null` and missing fields. For more information, see [How to filter for `null` and missing fields](#how-to-filter-for-null-and-missing-fields)

- **Enabling replication**: Prisma ORM uses [MongoDB transactions](https://www.mongodb.com/docs/manual/core/transactions/) internally to avoid partial writes on nested queries. When using transactions, MongoDB requires replication of your data set to be enabled. To do this, you will need to configure a [replica set](https://www.mongodb.com/docs/manual/replication/) — this is a group of MongoDB processes that maintain the same data set. Note that it is still possible to use a single database, by creating a replica set with only one node in it. If you use MongoDB's [Atlas](https://www.mongodb.com/atlas/database) hosting service, the replica set is configured for you, but if you are running MongoDB locally you will need to set up a replica set yourself. For more information, see MongoDB's [guide to deploying a replica set](https://www.mongodb.com/docs/manual/tutorial/deploy-replica-set/).

### Performance considerations for large collections
#### Problem 
When working with large MongoDB collections through Prisma, certain operations can become slow and resource-intensive. In particular, operations that require scanning the entire collection, such as `count()`, can hit query execution time limits and significantly impact performance as your dataset grows.

#### Solution
To address performance issues with large MongoDB collections, consider the following approaches:

1. For large collections, consider using MongoDB's `estimatedDocumentCount()` instead of `count()`. This method is much faster as it uses metadata about the collection. You can use Prisma's `runCommandRaw` method to execute this command.

2. For frequently accessed counts, consider implementing a counter cache. This involves maintaining a separate document with pre-calculated counts that you update whenever documents are added or removed.


## How to use Prisma ORM with MongoDB

This section provides instructions for how to carry out tasks that require steps specific to MongoDB.

### How to migrate existing data to match your Prisma schema

Migrating your database over time is an important part of the development cycle. During development, you will need to update your Prisma schema (for example, to add new fields), then update the data in your development environment’s database, and eventually push both the updated schema and the new data to the production database.

:::info

When using MongoDB, be aware that the “coupling” between your schema and the database is purposefully designed to be less rigid than with SQL databases; MongoDB will not enforce the schema, so you have to verify data integrity.

:::

These iterative tasks of updating the schema and the database can result in inconsistencies between your schema and the actual data in the database. Let’s look at one scenario where this can happen, and then examine several strategies for you and your team to consider for handling these inconsistencies.

**Scenario**: you need to include a phone number for users, as well as an email. You currently have the following `User` model in your `schema.prisma` file:

```prisma file=prisma/schema.prisma showLineNumbers
model User {
  id    String @id @default(auto()) @map("_id") @db.ObjectId
  email String
}
```

There are a number of strategies you could use for migrating this schema:

- **"On-demand" updates**: with this strategy, you and your team have agreed that updates can be made to the schema as needed. However, in order to avoid migration failures due to inconsistencies between the data and schema, there is agreement in the team that any new fields added are explicitly defined as optional.

  In our scenario above, you can add an optional `phoneNumber` field to the `User` model in your Prisma schema:

  ```prisma file=prisma/schema.prisma highlight=4;add showLineNumbers
  model User {
    id          String  @id @default(auto()) @map("_id") @db.ObjectId
    email       String
    //add-next-line
    phoneNumber String?
  }
  ```

  Then regenerate your Prisma Client using the `npx prisma generate` command. 
  
  Next, update your application to reflect the new field, and redeploy your app.

  As the `phoneNumber` field is optional, you can still query the old users where the phone number has not been defined. The records in the database will be updated "on demand" as the application's users begin to enter their phone number in the new field.

  Another option is to add a default value on a required field, for example:

  ```prisma file=prisma/schema.prisma highlight=4;add showLineNumbers
  model User {
    id          String @id @default(auto()) @map("_id") @db.ObjectId
    email       String
    //add-next-line
    phoneNumber String @default("000-000-0000")
  }
  ```

  Then when you encounter a missing `phoneNumber`, the value will be coerced into `000-000-0000`.

- **"No breaking changes" updates**: this strategy builds on the first one, with further consensus amongst your team that you don't rename or delete fields, only add new fields, and always define the new fields as optional. This policy can be reinforced by adding checks in the CI/CD process to verify that there are no backwards-incompatible changes to the schema.

- **"All-at-once" updates**: this strategy is similar to traditional migrations in relational databases, where all data is updated to reflect the new schema. In the scenario above, you would create a script to add a value for the phone number field to all existing users in your database. You can then make the field a required field in the application because the schema and the data are consistent.

### How to add in missing relations after Introspection

After introspecting an existing MongoDB database, you will need to manually add in relations between models. MongoDB does not have the concept of defining relations via foreign keys, as you would in a relational database. However, if you have a collection in MongoDB with a "foreign-key-like" field that matches the ID field of another collection, Prisma ORM will allow you to emulate relations between the collections.

As an example, take a MongoDB database with two collections, `User` and `Post`. The data in these collections has the following format, with a `userId` field linking users to posts:

`User` collection:

- `_id` field with a type of `objectId`
- `email` field with a type of `string`

`Post` collection:

- `_id` field with a type of `objectId`
- `title` field with a type of `string`
- `userId` with a type of `objectID`

On introspection with `db pull`, this is pulled in to the Prisma Schema as follows:

```prisma file=prisma/schema.prisma showLineNumbers
model Post {
  id     String @id @default(auto()) @map("_id") @db.ObjectId
  title  String
  userId String @db.ObjectId
}

model User {
  id    String @id @default(auto()) @map("_id") @db.ObjectId
  email String
}
```

This is missing the relation between the `User` and `Post` models. To fix this, manually add a `user` field to the `Post` model with a `@relation` attribute using `userId` as the `fields` value, linking it to the `User` model, and a `posts` field to the `User` model as the back relation:

```prisma file=prisma/schema.prisma highlight=5;add|11;add showLineNumbers
model Post {
  id     String @id @default(auto()) @map("_id") @db.ObjectId
  title  String
  userId String @db.ObjectId
  //add-next-line
  user   User   @relation(fields: [userId], references: [id])
}

model User {
  id    String @id @default(auto()) @map("_id") @db.ObjectId
  email String
  //add-next-line
  posts Post[]
}
```

For more information on how to use relations in Prisma ORM, see [our documentation](/orm/prisma-schema/data-model/relations).

### How to filter for `null` and missing fields

To understand how MongoDB distinguishes between `null` and missing fields, consider the example of a `User` model with an optional `name` field:

```ts
model User {
  id    String  @id @default(auto()) @map("_id") @db.ObjectId
  email String
  name  String?
}
```

First, try creating a record with the `name` field explicitly set to `null`. Prisma ORM will return `name: null` as expected:

<CodeWithResult expanded={true}>

<cmd>

```ts
const createNull = await prisma.user.create({
  data: {
    email: 'user1@prisma.io',
    name: null,
  },
})
console.log(createNull)
```

</cmd>

<cmdResult>

```code no-copy
{
  id: '6242c4ae032bc76da250b207',
  email: 'user1@prisma.io',
  name: null
}
```

</cmdResult>

</CodeWithResult>

If you check your MongoDB database directly, you will also see a new record with `name` set to `null`:

```json
{
  "_id": "6242c4af032bc76da250b207",
  "email": "user1@prisma.io",
  "name": null
}
```

Next, try creating a record without explicitly setting the `name` field:

<CodeWithResult expanded={true}>

<cmd>

```ts
const createMissing = await prisma.user.create({
  data: {
    email: 'user2@prisma.io',
  },
})
console.log(createMissing)
```

</cmd>

<cmdResult>

```code no-copy
{
  id: '6242c4ae032bc76da250b208',
  email: 'user2@prisma.io',
  name: null
}
```

</cmdResult>

</CodeWithResult>

Prisma ORM still returns `name: null`, but if you look in the database directly you will see that the record has no `name` field defined at all:

```json
{
  "_id": "6242c4af032bc76da250b208",
  "email": "user2@prisma.io"
}
```

Prisma ORM returns the same result in both cases, because we currently don't have a way to specify this difference in MongoDB between fields that are `null` in the underlying database, and fields that are not defined at all — see [this Github issue](https://github.com/prisma/prisma/issues/12555) for more information.

This means that you currently have to be careful when filtering for `null` and missing fields. Filtering for records with `name: null` will only return the first record, with the `name` explicitly set to `null`:

<CodeWithResult expanded={true}>

<cmd>

```ts
const findNulls = await prisma.user.findMany({
  where: {
    name: null,
  },
})
console.log(findNulls)
```

</cmd>

<cmdResult>

```terminal no-copy
[
  {
    id: '6242c4ae032bc76da250b207',
    email: 'user1@prisma.io',
    name: null
  }
]
```

</cmdResult>

</CodeWithResult>

This is because `name: null` is checking for equality, and a non-existing field isn't equal to `null`.

To include missing fields as well, use the [`isSet` filter](/orm/reference/prisma-client-reference#isset) to explicitly search for fields which are either `null` or not set. This will return both records:

<CodeWithResult expanded={true}>

<cmd>

```ts
const findNullOrMissing = await prisma.user.findMany({
  where: {
    OR: [
      {
        name: null,
      },
      {
        name: {
          isSet: false,
        },
      },
    ],
  },
})
console.log(findNullOrMissing)
```

</cmd>

<cmdResult>

```terminal no-copy
[
  {
    id: '6242c4ae032bc76da250b207',
    email: 'user1@prisma.io',
    name: null
  },
  {
    id: '6242c4ae032bc76da250b208',
    email: 'user2@prisma.io',
    name: null
  }
]
```

</cmdResult>

</CodeWithResult>

## More on using MongoDB with Prisma ORM

The fastest way to start using MongoDB with Prisma ORM is to refer to our Getting Started documentation:

- [Start from scratch](/getting-started/prisma-orm/quickstart/mongodb)
- [Add to existing project](/getting-started/prisma-orm/add-to-existing-project/mongodb)

These tutorials will take you through the process of connecting to MongoDB, pushing schema changes, and using Prisma Client.

Further reference information is available in the [MongoDB connector documentation](/orm/overview/databases/mongodb).

For more information on how to set up and manage a MongoDB database, see the [Prisma Data Guide](https://www.prisma.io/dataguide#mongodb).

## Example

To connect to a MongoDB server, configure the [`datasource`](/orm/prisma-schema/overview/data-sources) block in your [Prisma Schema](/orm/prisma-schema):

```prisma file=schema.prisma showLineNumbers
datasource db {
  provider = "mongodb"
  url      = env("DATABASE_URL")
}
```

The fields passed to the `datasource` block are:

- `provider`: Specifies the `mongodb` data source connector.
- `url`: Specifies the [connection URL](#connection-url) for the MongoDB server. In this case, an [environment variable is used](/orm/more/development-environment/environment-variables) to provide the connection URL.

:::warning

The MongoDB database connector uses transactions to support nested writes. Transactions **require** a [replica set](https://www.mongodb.com/docs/manual/tutorial/deploy-replica-set/) deployment. The easiest way to deploy a replica set is with [Atlas](https://www.mongodb.com/docs/atlas/getting-started/). It's free to get started.

:::

## Connection details

### Connection URL

The MongoDB connection URL can be configured in different ways depending on how you are hosting your database. The standard configuration is made up of the following components:

![Structure of the MongoDB connection URL](./mongodb.png)

#### Base URL and path

The base URL and path sections of the connection URL are made up of your authentication credentials followed by the host (and optionally, a port number) and database.

```
mongodb://USERNAME:PASSWORD@HOST/DATABASE
```

The following components make up the _base URL_ of your database:

| Name     | Placeholder | Description                                                                                                                                                                                                                                                                                                                                                |
| :------- | :---------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| User     | `USERNAME`  | Name of your database user, e.g. `janedoe`                                                                                                                                                                                                                                                                                                                 |
| Password | `PASSWORD`  | Password for your database user                                                                                                                                                                                                                                                                                                                            |
| Host     | `HOST`      | The host where a [`mongod`](https://www.mongodb.com/docs/manual/reference/program/mongod/#mongodb-binary-bin.mongod) instance is running. If you are running a sharded cluster this will a [`mongos`](https://www.mongodb.com/docs/manual/reference/program/mongos/#mongodb-binary-bin.mongos) instance. This can be a hostname, IP address or UNIX domain socket. |
| Port     | `PORT`      | Port on which your database server is running, e.g. `1234`. If none is provided the default `27017` is used.                                                                                                                                                                                                                                               |
| Database | `DATABASE`  | Name of the database to use. If none is specified but the `authSource` option is set then the `authSource` database name is used. If neither the database in the connection string nor the `authSource` option is specified then it defaults to `admin`                                                                                                    |

:::info

You must [percentage-encode special characters](/orm/reference/connection-urls#special-characters).

:::

#### Arguments

A connection URL can also take arguments. The following example sets three arguments:

- An `ssl` connection
- A `connectTimeoutMS`
- And the `maxPoolSize`

```
mongodb://USERNAME:PASSWORD@HOST/DATABASE?ssl=true&connectTimeoutMS=5000&maxPoolSize=50
```

Refer to the [MongoDB connection string documentation](https://www.mongodb.com/docs/manual/reference/connection-string/) for a complete list of connection string arguments. There are no Prisma ORM-specific arguments.

## Using `ObjectId`

It is common practice for the `_id` field of a MongoDB document to contain an [ObjectId](https://www.mongodb.com/docs/manual/reference/bson-types/#std-label-objectid):

```json
{
  "_id": { "$oid": "60d599cb001ef98000f2cad2" },
  "createdAt": { "$date": { "$numberLong": "1624611275577" } },
  "email": "ella@prisma.io",
  "name": "Ella",
  "role": "ADMIN"
}
```

Any field (most commonly IDs and relation scalar fields) that maps to an `ObjectId` in the underlying database:

- Must be of type `String` or `Bytes`
- Must include the `@db.ObjectId` attribute
- Can optionally use `@default(auto())` to auto-generate a valid `ObjectId` on document creation

Here is an example that uses `String`:

```prisma
model User {
  id String @id @default(auto()) @map("_id") @db.ObjectId
  // Other fields
}
```

And here is another example that uses `Bytes`:

```prisma
model User {
  id Bytes @id @default(auto()) @map("_id") @db.ObjectId
  // Other fields
}
```

See also: [Defining ID fields in MongoDB](/orm/prisma-schema/data-model/models#defining-ids-in-mongodb)

### Generating `ObjectId`

To generate a valid `ObjectId` (for testing purposes or to manually set an ID field value) in your application, use the [`bson`](https://www.npmjs.com/package/bson) package.

```
npm install --save bson
```

```ts
import { ObjectId } from 'bson'

const id = new ObjectId()
```

## Differences to connectors for relational databases

This section covers ways in which the MongoDB connector differs from Prisma ORM connectors for relational databases.

### No support for Prisma Migrate

Currently, there are no plans to add support for [Prisma Migrate](/orm/prisma-migrate) as MongoDB projects do not rely on internal schemas where changes need to be managed with an extra tool. Management of `@unique` indexes is realized through `db push`.

### No support for `@@id` and `autoincrement()`

The [`@@id`](/orm/reference/prisma-schema-reference#id-1) attribute (an ID for multiple fields) is not supported because primary keys in MongoDB are always on the `_id` field of a model.

The [`autoincrement()`](/orm/reference/prisma-schema-reference#generate-autoincrementing-integers-as-ids-relational-databases-only) function (which creates incrementing `@id` values) is not supported because `autoincrement()` does not work with the `ObjectID` type that the `_id` field has in MongoDB.

### Cyclic references and referential actions

If you have cyclic references in your models, either from self-relations or a cycle of relations between models, and you use [referential actions](/orm/prisma-schema/data-model/relations/referential-actions), you must set a referential action of `NoAction` to prevent an infinite loop of actions.

See [Special rules for referential actions](/orm/prisma-schema/data-model/relations/referential-actions/special-rules-for-referential-actions) for more details.

### Replica set configuration

MongoDB only allows you to start a transaction on a replica set. Prisma ORM uses transactions internally to avoid partial writes on nested queries. This means we inherit the requirement of needing a replica set configured.

When you try to use Prisma ORM's MongoDB connector on a deployment that has no replica set configured, Prisma ORM shows the message `Error: Transactions are not supported by this deployment`. The full text of the error message is the following:

```
PrismaClientUnknownRequestError2 [PrismaClientUnknownRequestError]:
Invalid `prisma.post.create()` invocation in
/index.ts:9:21

   6 await prisma.$connect()
   7
   8 // Create the first post
→  9 await prisma.post.create(
  Error in connector: Database error. error code: unknown, error message: Transactions are not supported by this deployment
    at cb (/node_modules/@prisma/client/runtime/index.js:34804:17)
    at processTicksAndRejections (internal/process/task_queues.js:97:5) {
  clientVersion: '3.xx.0'
}
```

To resolve this, we suggest you change your deployment to one with a replica set configured.

One simple way for this is to use [MongoDB Atlas](https://www.mongodb.com/cloud/atlas) to launch a free instance that has replica set support out of the box.

There's also an option to run the replica set locally with this guide: https://www.mongodb.com/docs/manual/tutorial/convert-standalone-to-replica-set

## Type mapping between MongoDB and the Prisma schema

The MongoDB connector maps the [scalar types](/orm/prisma-schema/data-model/models#scalar-fields) from the Prisma ORM [data model](/orm/prisma-schema/data-model/models) to MongoDB's native column types as follows:

> Alternatively, see [Prisma schema reference](/orm/reference/prisma-schema-reference#model-field-scalar-types) for type mappings organized by Prisma type.

### Native type mapping from Prisma ORM to MongoDB

| Prisma ORM | MongoDB                                                                |
| ---------- | ---------------------------------------------------------------------- |
| `String`   | `string`                                                               |
| `Boolean`  | `bool`                                                                 |
| `Int`      | `int`                                                                  |
| `BigInt`   | `long`                                                                 |
| `Float`    | `double`                                                               |
| `Decimal`  | [Currently unsupported](https://github.com/prisma/prisma/issues/12637) |
| `DateTime` | `timestamp`                                                            |
| `Bytes`    | `binData`                                                              |
| `Json`     |                                                                        |

MongoDB types that are currently unsupported:

- `Decimal128`
- `Undefined`
- `DBPointer`
- `Null`
- `Symbol`
- `MinKey`
- `MaxKey`
- `Object`
- `Javascript`
- `JavascriptWithScope`
- `Regex`

### Mapping from MongoDB to Prisma ORM types on Introspection

When introspecting a MongoDB database, Prisma ORM uses the relevant [scalar types](/orm/prisma-schema/data-model/models#scalar-fields). Some special types also get additional native type annotations:

| MongoDB (Type \| Aliases) | Prisma ORM | Supported | Native database type attribute | Notes |
| ------------------------- | ---------- | :-------: | :----------------------------- | :---- |
| `objectId`                | `String`   |    ✔️     | `@db.ObjectId`                 |       |

[Introspection](/orm/prisma-schema/introspection) adds native database types that are **not yet supported** as [`Unsupported`](/orm/reference/prisma-schema-reference#unsupported) fields:

```prisma file=schema.prisma showLineNumbers
model Example {
  id    String                           @id @default(auto()) @map("_id") @db.ObjectId
  name  String
  regex Unsupported("RegularExpression")
}
```
